Router : Web router
A router
object is an isolated instance of middleware and routes. You can think of it as a “mini-application," capable only of performing middleware and routing functions. Every application has a built-in app router.
A router behaves like middleware itself, so you can use it as an argument to app.use()
or as the argument to another router’s use()
method.
Once you’ve created a router object, you can add middleware and HTTP method routes (such as get
, put
, post
, and so on) to it just like an application. For example:.
// invoked for any requests passed to this router
router.use(function (req, res) {
// .. some logic here .. like any other middleware
})
// will handle any request that ends in /events depends on where the router is "use()'d"
router.get('/events', function (req, res) {
// ..
})
You can then use a router for a particular root URL in this way separating your routes into files or even mini-apps.
// only requests to /calendar/* will be sent to our "router"
app.use('/calendar', router);
You can also creates router object from Router module. User can use the following code to import the Router
module.
var Router = require('webapp').Router;
Or:
var Router = require('web_router');
Support
The following shows Router
module APIs available for each permissions.
User Mode | Privilege Mode | |
---|---|---|
Router.create | ● | ● |
router.METHOD | ● | ● |
router.all | ● | ● |
router.use | ● | ● |
router.route | ● | ● |
Router Class
Router.create([options])
options
{Object} options:caseSensitive
{Boolean} Enable case sensitivity. default: false - disabled by default, treating “/Foo” and “/foo” as the same.mergeParams
{Boolean} Preserve thereq.params
values from the parent router. If the parent and the child have conflicting param names, the child’s value take precedence. default: false.strict
{Boolean} Enable strict routing. default: false - “/foo” and “/foo/” are treated the same by the router. Create a new router object.
Example
var Router = require('webapp').Router;
var router = Router.create();
app.use(router);
Router Object
router.METHOD([path, ]handle[, handle..])
path
{String | RegExp | Array} The path for which the request handle function is invoked; can be any of:- A string representing a path. default: '/' (root path)
- A path pattern.
- A regular expression pattern to match paths.
- An array of combinations of any of the above.
handle
{Function} The request handle function.Router
supportasync
handle, see Async Handle for details.
The router.METHOD()
methods provide the routing functionality in WebApp , where METHOD is one of the HTTP methods, such as GET, PUT, POST, and so on, in lowercase. Thus, the actual methods are router.get()
, router.post()
, router.put()
, and so on. METHOD see app.METHOD()
.
Example
The following snippet illustrates the most simple route definition possible. WebApp translates the path strings to regular expressions, used internally to match incoming requests. Query strings are not considered when performing these matches, for example "GET /"
would match the following route, as would "GET /?name=tobi"
.
router.get('/', function (req, res) {
res.send('hello world');
})
You can also use regular expressions—useful if you have very specific constraints, for example the following would match "GET /commits/71dbb9c"
as well as "GET /commits/71dbb9c..4c084f9"
.
router.get(/^\/commits\/(\w+)(?:\.\.(\w+))?$/, function (req, res) {
var from = req.params[0];
var to = req.params[1] || 'HEAD';
res.send('commit range ' + from + '..' + to);
});
router.all([path, ]handle[, handle..])
path
{String | RegExp | Array} The path for which the request handle function is invoked; can be any of:- A string representing a path. default: '/' (root path)
- A path pattern.
- A regular expression pattern to match paths.
- An array of combinations of any of the above.
handle
{Function} The request handle function.Router
supportasync
handle, see Async Handle for details.
This method is just like the router.METHOD()
methods, except that it matches all HTTP methods (verbs).
Example
This method is extremely useful for mapping "global" logic for specific path prefixes or arbitrary matches. For example, if you placed the following route at the top of all other route definitions, it would require that all routes from that point on would require authentication, and automatically load a user. Keep in mind that these callbacks do not have to act as end points; loadUser
can perform a task, then continue matching subsequent routes.
router.all('*', requireAuthentication);
router.all('*', loadUser);
Another example of this is white-listed "global" functionality. Here the example is much like before, but it only restricts paths prefixed with "/api":
router.all('/api/*', requireAuthentication);
router.route([path])
path
{String | RegExp} route path.- A string representing a path. default: '/' (root path)
- A path pattern.
- A regular expression pattern to match paths.
- Returns {Object} an instance of a
Router
.
Returns an instance of a single route which you can then use to handle HTTP verbs with optional middleware. Use router.route()
to avoid duplicate route naming and thus typing errors.
Example
Tthe following code shows how to use router.route()
to specify various HTTP method handlers. This approach re-uses the single /users/:user_id
path and adds handlers for various HTTP methods.
var router = Router.create();
router.route('/users/:user_id')
.all(function (req, res) {
// runs for all HTTP verbs first
// think of it as route specific middleware!
})
.get(function (req, res) {
res.json(req.params.user_id);
})
.put(function (req, res) {
// just an example of maybe updating the user
req.user.name = req.params.name;
// save user ... etc
res.json(req.user);
})
.post(function (req, res) {
res.status(403);
res.send('not implemented');
})
.delete(function (req, res) {
res.status(403);
res.send('not implemented');
});
router.use([path, ]handle[, handle..])
path
{String | RegExp | Array} The path for which the middleware function is invoked; can be any of:- A string representing a path. default: '/' (root path)
- A path pattern.
- A regular expression pattern to match paths.
- An array of combinations of any of the above.
handle
{Function | Object} A middleware function or router object.Router
supportasync
handle, see Async Handle for details.
Uses the specified middleware function, with optional mount path path
, that defaults to "/"
.
Example
This method is similar to app.use()
. A simple example and use case is described below. See app.use()
for more information.
Middleware is like a plumbing pipe: requests start at the first middleware function defined and work their way "down" the middleware stack processing for each path they match.
var WebApp = require('webapp');
var Router = WebApp.Router;
var app = WebApp.create('example', 0, socket.sockaddr(socket.INADDR_ANY, 8000));
var router = Router.create();
// simple logger for this router's requests
// all requests to this router will first hit this middleware
router.use(function (req, res) {
console.log(`${req.methodInfo} ${req.url} ${req.path}`);
});
// this will only be invoked if the path starts with /bar from the mount point
router.use('/bar', function (req, res) {
// ... maybe some additional /bar logging ...
});
// always invoked
router.use(function (req, res) {
res.send('Hello World');
});
app.use('/foo', router);
app.start();
The "mount" path is stripped and is not visible to the middleware function. The main effect of this feature is that a mounted middleware function may operate without code changes regardless of its "prefix" pathname.
The order in which you define middleware with router.use()
is very important. They are invoked sequentially, thus the order defines middleware precedence. For example, usually a logger is the very first middleware you would use, so that every request gets logged.
var mw = require('middleware');
router.use(logger/* assume logger middleware */);
router.use(mw.serveStatic('/root/net/public'));
router.use(function (req, res) {
res.send('Hello');
});
Now suppose you wanted to ignore logging requests for static files, but to continue logging routes and middleware defined after logger. You would simply move the call to
mw.serveStatic()` to the top, before adding the logger middleware:
router.use(mw.serveStatic('/root/net/public'));
router.use(logger());
router.use(function (req, res) {
res.send('Hello');
});
Another example is serving files from multiple directories, giving precedence to "./public" over the others:
router.use(mw.serveStatic('/root/net/public')));
router.use(mw.serveStatic('/root/net/files')))
router.use(mw.serveStatic('/root/net/uploads')));
The router.use()
method also supports named parameters so that your mount points for other routers can benefit from preloading using named parameters.